home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 44 / Amiga Format CD44 (1999-08-26)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-10].iso / -in_the_mag- / basics / blitz / gorny3dset.lha / 3DLIBRARY.DOC < prev    next >
Text File  |  1996-01-14  |  20KB  |  601 lines

  1.  
  2. *********************************************
  3. *                                           *
  4. *                                           *
  5. *   3D Graphics Library for Blitz Basic II  *
  6. *                                           *
  7. *                                           *
  8. *            Version 0.9 Beta               *
  9. *                                           *
  10. *      2B3D (C) 1996 Maciej R. Gorny        *
  11. *                                           *
  12. *********************************************
  13.  
  14. CONTENT
  15.  
  16. 1]    HELLO
  17. 2]    3D COORDINATE SYSTEM
  18. 3]    POLYGONS SUPPORTED
  19. 4]    3D COMMANDS
  20. 5]    3D WORLD LIMITS
  21. 6]    DATA STRUCTURES AND NEWTYPES
  22. 7]    PLG - 3D OBJECT FILE FORMAT
  23. 8]    THINGS TO WATCH OUT FOR
  24. 9]    CONTACTING AUTHOR
  25.  
  26.  
  27.  
  28. 1]    HELLO
  29. _____________________________________________________________________________
  30.  
  31. My main goal was to have a set of functions (or statements) which would
  32. allow me to create 3D programs, mainly I was thinking about games here, but not
  33. only. Well, I run out of time to complete any particular program and this
  34. set of functions is as far as I got. I haven't been able to test in on
  35. machine other than mine, which is 68000 powered A2000 with 1.3 Workbench so
  36. I don't think there should be any problems on other machines.
  37.  
  38. It is rather modest library. It does not support things like z-buffer, texture
  39. mapping, or BSP. It simply reads objects in a format transforms between
  40. different coordinate systems (object's local, world, and camera coordinates)
  41. and projects the resulting image made up of polygons onto current screen.
  42. It also performs backface culling to reduce number of polygons projected,
  43. and either one (z) plane clipping or the entire viewing volume clipping
  44. (frustum). It also shades the polygons in rather simple manner to give a bit
  45. more depth and make it look better.
  46.  
  47. I did not use z-buffer here. I found that scan converting each polygon about to
  48. be drawn and calculating z-axis values of each pixel in a polygon to be too
  49. much to handle for my Amiga. Also, Blitz2 does not provide any easy way to
  50. allocate global array from within a function so the only way I could think of
  51. to implement z-buffer would be to DIM an array and provide only one z-buffer
  52. size. Besides, z-buffer uses a lot of memory, so this is a task for later
  53. updates of the library. The library uses a variant of so called painter's
  54. algorythm to find out which polygons should be drawn first, and draws them
  55. in back-to-front order. This solution may cause some problems if there are
  56. many objects and very close to each other, but with careful planning those
  57. problems can be avoided.
  58.  
  59. Once I get this version a bit more optimized, so performance is more acceptable,
  60. I will add z-buffer functions, as well as better light sourcing functions.
  61. For example right now it does not matter how far away is a light source located
  62. from the objects. Also I will add Gouraud shading and maybe even texture
  63. mapping if I get it to run at decent speeds.
  64.  
  65. The library is really slow at this stage. That's because this version is
  66. not completely optimized yet, and most of all is written fully in Blitz2.
  67. It contains no assembly code whatsoever, due to the fact that I don't know
  68. anything about 68000 assembly. Some inner loops could probably benefit greatly
  69. from some assembly, as could the entire library I suppose.
  70.  
  71. This is the beta release of the software library and as such may contain some
  72. bugs. If you find any please do not hesitate to contact me and let me know:
  73.  
  74. Maciej Gorny
  75. gorn4907@mars.rowan.edu
  76. or: 424A Victoria Ave.
  77.     Glassboro, NJ 08028, USA
  78.  
  79. Some of the bugs were especially hard to figure out. RotateObject()
  80. function for example takes four parameter. Three being the angles and
  81. another serves as padding of some sort, without which last parameter
  82. (z-axis angle) had been corrupted. I couldn't find a reason for that, I
  83. just found the solution which makes RotateObject() work.
  84.  
  85. If you have any questions, please don't hesitate to send me email or write.
  86.  
  87.  
  88.  
  89. 2]    3D COORDINATES SYSTEM
  90. _____________________________________________________________________________
  91.  
  92. Coordinate system used is a left-handed coordinate system: X-axis goes from left
  93. to right, Y-axis, from down up-wards, and Z-axis from behind (us) into the
  94. screen.
  95.  
  96.                ^ +Y
  97.                |        Into the screen
  98.                |
  99.                |      +Z
  100.                |     /
  101.                |    /
  102.                |   /
  103.                |  /
  104.                | /
  105.                |/
  106. -X ---------------------------> +X
  107.               /|
  108.              / |
  109.             /  |
  110.            /   |
  111.           /    |
  112.        -Z/     |
  113.                |
  114.  Viewer        | -Y
  115.  
  116.  
  117.  
  118.  
  119. 3]    POLYGONS SUPPORTED
  120. _____________________________________________________________________________
  121.  
  122. 2B3D supports polygons with three vertices (triangles) and the ones with four
  123. vertices (quads). All other will be either rejected or will cause problems.
  124. Polygons can be one-sided or two-sided.
  125.  
  126. One-sided polygons will be visible only when they are facing a viewer. This is
  127. useful if we want to limit number of polygons rendered to screen by using
  128. backface culling and remove polygons that cannot be seen in an object. Objects
  129. cannot concave in such case.
  130.  
  131. Two-sided polygons will always be rendered to a screen (provided they get
  132. passed clipping procedures), because they have two sides that are visible to
  133. a viewer: front and back.
  134.  
  135.  
  136.  
  137. 4]    3D COMMANDS
  138. _____________________________________________________________________________
  139.  
  140. Here's a list of commands in current version of 2B3D Library. A lot of them are
  141. used internally by the system and end user will never have to use them, but I
  142. included their descriptions anyway just so maybe someone will find them useful
  143. somewhere else (like matrix multiplication, or vector math).
  144.  
  145.  
  146.  
  147. Display3D(w.l, h.l, d.l)
  148.  
  149.     w = current screen width
  150.     h = current screen height
  151.     d = distance from viewer to projection plane
  152.  
  153.     This must be called before any of the 3d functions can be used. 
  154.     It precalculates some parameters needed by 3d engine and
  155.         establishes some default setting used bu the system (i.e. light
  156.         source, front and back clipping planes, etc...)
  157.  
  158. BuildLookUpTables()
  159.  
  160.     Builds look up tables needed by the 3d system. This function is
  161.         automatically called by Display3D. Calling it again by a user
  162.     would be redundant and pointless.
  163.  
  164. AspectRatio{aspect.f}
  165.  
  166.     aspect = an aspect ratio fraction
  167.  
  168.     This function may be used to change screens aspect ration.
  169.     If a screen is 640x200 squares will look more like rectangles, and
  170.     circles like ovals. Best example of aspect ratio at work is to set
  171.     up your world the way you want it on a display with 1:1 aspect
  172.     ratio (or as close as possible) like 320x200 screen or 640x400.
  173.     Then change the display to something like 640x200 to see the effect.
  174.     I found aspect ratio=0.55 for 640x200 screen adequate and 1.55 for
  175.     screen 320x400.
  176.  
  177.     Call this function to change the default aspect ratio (default=1).
  178.  
  179. MakeVector3D(a.vertex, b.vertex, r.vector)
  180.  
  181.     Creates a vector (r) out of two vertices a and b.
  182.  
  183. VectorMag3D(v.vector)
  184.  
  185.     Returns (float) a magnitude of a vector v.
  186.  
  187. DotProduct(u.vector, v.vector)
  188.  
  189.     Returns (float) a dot product of two vectors. 
  190.  
  191. CrossProduct(u.vector, v.vector, r.vector)
  192.  
  193.     Finds a cross product of two vectors resulting in normal vector.
  194.     Normal vector is the one that is perpendicular to both vectors.
  195.  
  196. MatIdentity4x4(m.matrix4x4)
  197.  
  198.     Initializes a matrix (m) to become an identity matrix.
  199.  
  200. MatZero4x4(m.matrix4x4)
  201.  
  202.     Completely empties out a 4x4 matrix (sets it to 0s).
  203.  
  204. MatCopy4x4(s.matrix4x4, d.matrix4x4)
  205.  
  206.     Copies a 4x4 source matrix (s) into a 4x4 destinatio matrix (d).
  207.  
  208. MatPrint4x4(m.matrix4x4)
  209.  
  210.     Prints out content of a matrix (m) into output channel.
  211.  
  212. MatPrint1x4(m.matrix1x4)
  213.  
  214.     Prints out content of a 1x4 matrix (m).
  215.  
  216. MatMult4x4(m.matrix4x4, n.matrix4x4, r.matri4x4)
  217.  
  218.     Multiplies two 4x4 matrices together (m and n) and stores the result
  219.     in another 4x4 matrix (r).
  220.  
  221. MatMult4x4S{m.matrix4x4, n.matrix4x4, r.matrix4x4}
  222.  
  223.     This is a special version of MatMult4x4 which is optimized for 
  224.     multiplying matrices which contain rotation tranformations.
  225.     It is almost 50% faster than MatMult4x4().
  226.  
  227. MatMult1x4(a.matrix1x4, b.matrix4x4, r.matrix1x4)
  228.  
  229.     Multiplies a 1x4 matrix (a) and 4x4 matrix (b) and stores the result 
  230.     in a 1x4 matrix (r).
  231.  
  232. PLGGetLine(string.s)
  233.  
  234.     Internal function. Used by PLG loader.
  235.  
  236. ComputeObjectRadius()
  237.  
  238.     Internal function used by PLG loader.
  239.  
  240. PLGLoadObject(filename.s, scalar.f)
  241.  
  242.     filename = file location on a disk.
  243.       scalar = scale factor
  244.  
  245.     Loads a 3d object stored in a PLG like file format. An object may
  246.     be scaled as it is loaded by a scale factor. Set scale factor to 1,
  247.     if no scaling is desired.
  248.  
  249.     Objects are loaded into a LIST type array, so most recently loaded
  250.     object becomes currently used object.
  251.  
  252. ObjectPrint()
  253.  
  254.     Prints out all the information about currently used object.
  255.  
  256. TranslateObject(dx.l, dy.l, dz.l)
  257.  
  258.     Moves currently used object into a new position in 3d world.
  259.  
  260. PositionObject(x.l, y.l, z.l)
  261.  
  262.     Positions currently used object in a 3d world space. Should be called
  263.     right after an object is loaded, because by default loaded objects are
  264.     located at (0,0,0) world coordinates.
  265.  
  266. ScaleObject(s.f)
  267.  
  268.     s = scale factor
  269.  
  270.     Scales currently used object by scale factor.
  271.     if 0<s<1, object will shrink (0.5 is half the size)
  272.     if   s=1, no change in object size
  273.     if   s>1, object will be enlarged 
  274.  
  275. RotateObject(rx,ry,pad,rz)
  276.  
  277.     rx = degrees around X-axis
  278.     ry = degrees aroumd Y-axis
  279.     rz = degrees around Z-axis
  280.  
  281.     pad= A dummy parameter to avoid Blitz2 corrupting rz parameter.
  282.          This is one of those bugs that I couldn't figure out. Seems
  283.          to work fine this way. I usually pass it as 0.
  284.  
  285.     Rotates currently used object around X,Y, and Z (local) axis.
  286.  
  287. DrawTopTriangle(p1.pixel, p2.pixel, p3.pixel, color.w)
  288.  
  289.     Draws a triangle with a flat top:
  290.     Serves as an internal function.
  291.                       p1______p2
  292.                        |      /
  293.                        |     /
  294.                        |    /
  295.                        |   /
  296.                        |  /    Points can be in any order.
  297.                        | /
  298.                        |/p3
  299.  
  300. DrawBottomTriangle(p1.pixel, p2.pixel, p3.pixel)
  301.  
  302.     Draws a triangle with a flat bottom:
  303.     Serves as an internal function.
  304.                         p1
  305.                         |\
  306.                         | \
  307.                         |  \ Points can be in any order
  308.                         |   \
  309.                         |    \
  310.                         |     \
  311.                           p3|______p2
  312.  
  313.  
  314. DrawTriangle2D{p1.pixel, p2.pixel, pad.w, p3.pixel)
  315.  
  316.     Draws any triangle with vetices p1, p2, and p3 on a screen.
  317.     pad is necessary to prevent corruption of p3 values.
  318.  
  319. SetTriangleColor(color)
  320.  
  321.     Sets a color used to draw triangles when using DrawTriangle2D function.
  322.     This parameter was supposed to be passed with the points when calling
  323.     the function, however, it kept corrupting the last point (p3).
  324.     \x and \y values received were different than the ones sent. This seems
  325.     to fix the problem.
  326.  
  327. ShowObjectWire()
  328.  
  329.     Displays a wireframe representation of a currently used object
  330.     using perspective projection.
  331.  
  332.  
  333. TouchPalette(first_reg, last_reg, init_color.rgbtype, final_color.rgbtype)
  334.  
  335.     Creates a palette for use with shading functions. Actually, it alters
  336.     existing current screen's palette. It will affect current palette's
  337.     registers between first_reg and last_reg, and it will interpolate
  338.     color values from init_color to final_color.
  339.  
  340.     ex.: I used a 16 color screen (registers 0-15). I wanted to have a
  341.          palette of 16 shades of gray where register 0 contains black,
  342.          and register 15 white color. To achieve this, we should use:
  343.  
  344.     c1.rgbtype\r=0,0,0:c2.rgbtype\r=15,15,15:TouchPalette(0,15,c1,c2)
  345.  
  346.     We also should make sure that objects which use that palette will
  347.     have color field specified to be 0 since shading is added as a
  348.     off of main color.
  349.  
  350.     If we used 32 color screen we could use shades of two colors, i.e.
  351.     shades of grey and red. Registers 0-15 would contain shades of grey,
  352.     and registers 16-31. 16 being deep dark red, and 31 white or very
  353.     bright red. Our polygons could have two colors then: 0 and 16
  354.     specified in the polygon color field.
  355.  
  356. RemoveBackfacesAndShade()
  357.  
  358.     Removes backfaces (invisible polygons with their back to viewer) and
  359.     calculates shade of their color. Uses current object.
  360.  
  361. DrawObjectSolid()
  362.  
  363.     Same a ShowObjectWire(), but renders currently used object in its
  364.     solid form.
  365.  
  366. LocalToWorld()
  367.  
  368.     Translates currently used object's local coordinates to world (global)
  369.     coordinates. Must be used everytime objects position has changed.
  370.  
  371. WorldToCamera()
  372.  
  373.     Translates currently used object's word coordinates to camera viewing
  374.     coordinates. Must be called every time viewer's position changes or
  375.     object's position changes.
  376.         Used internally.
  377.  
  378. CreateWorldToCamera()
  379.  
  380.     Creates a global, inverse transformation matrix used to transform world
  381.     coordinates to camera coordinates.
  382.     Used internally.
  383.  
  384. RemoveObject()
  385.  
  386.     Returns TRUE if currently used object is within viewing volume, FALSE
  387.     otherwise.
  388.  
  389. DeleteObject()
  390.  
  391.     Removes currently used object from 3d world system.
  392.  
  393. ClipMode(mode)
  394.  
  395.     Sets the clipping mode for use by the system.
  396.  
  397.         If mode==#FRUSTUM objects will be clipped against the entire
  398.         clipping volume.
  399.  
  400.         If mode==#ZPLANE objects will be clipped only against a
  401.         specified plane on Z axis. This plane is specified in
  402.         Frustum() function as 'near' parameter.
  403.  
  404. Frustum(near, far)
  405.  
  406.     Defines front and back clipping planes of the viewing volume on a Z
  407.     axis.
  408.  
  409. CreateLightSource(x,y,z)
  410.  
  411.     Creates a vector describing direction from which rays of light from
  412.     infinite light source are coming. This is very primitive light sourcing
  413.     and the distance of a light source away from the objects has no effect
  414.     on their shading.
  415.  
  416. PositionCamera(x,y,z)
  417.  
  418.     Places viewer (camera) in a 3d world at specified coordinates.
  419.  
  420. ViewAngle(angx, angy, angz)
  421.  
  422.     Spefies angle at which a viewer is looking at the 3d world.
  423.     If all angles are 0, viewer is looking straight ahead down
  424.     the positive direction of Z-axis.
  425.  
  426. ClipObject3D()
  427.  
  428.     Clips currently used object against viewing volume.
  429.  
  430. GeneratePolyList()
  431.  
  432.     Creates a list of all polygons used in one frame. Must be called before
  433.     using any of the special invisible surface removing fuctions. Also
  434.     must be called whenever objects were added or removed from the 3d world.
  435.     Used internally.
  436.  
  437. PaintFrame()
  438.  
  439.     Generates a view as seen from viewer's current position. This function
  440.     uses simple implementation of a popular Painter's algorythm to show
  441.     objects in correct order. The function sorts polygons according to their
  442.     maximum z values.
  443.  
  444.     Polygons and objects should not be allowed to intersect each other.
  445.     That's where shortcomings of that algorythm become visible, but
  446.     nevertheless creates some interesting effects I think.
  447.  
  448. NewView()
  449.  
  450.     Recalculates scenery and prepares it for display using PaintFrame().
  451.     This function should be called every time a scene has changed (i.e.
  452.     viewpoint has been moved, or viewing angle changed, or maybe a new
  453.     object entered a scene).
  454.  
  455.  
  456. MoveForward(dist)
  457.  
  458.         Moves a viewer forward by 'dist' units (duh!). To move back simply
  459.     enter negative value for dist.
  460.  
  461. MoveUp(dist)
  462.  
  463.         Relocates a viewer up the Y axis.
  464.  
  465. MoveDown(dist)
  466.  
  467.         Moves a viewer down the Y axis.
  468.  
  469. ObjectsUseColor(reg)
  470.  
  471.     Forces all objects in the 3d world to use 'reg' as the base for the
  472.     shading offset. Using TouchPalette() it is possible to specify only
  473.     part of any palette to hold shade variations of some color, and
  474.     using ObjectsUseColor() will force all objects to use our new base
  475.     and the offsets overriding whatever color field was specified in
  476.     object's PLG file.
  477.  
  478.         Example of using it and palette manipulation is in DEMO2.BB2
  479.  
  480. CameraX(), CameraY(), CameraZ()
  481.  
  482.         All functions return their relevant position in the 3d world.
  483.     They return long word (.l)
  484.  
  485. AngleX(), AngleY(), AngleZ()
  486.  
  487.     These functions return cameras viewing angles. They return long
  488.     value (.l)
  489.  
  490.  
  491.  
  492. 5]    3D WORLD LIMITS
  493. _____________________________________________________________________________
  494.  
  495. There are some limits involved such as how many vertices one polygon is
  496. allowed to have, how many polygons are allowed in an object. Here is
  497. the list:
  498.  
  499. MAXIMUM                       LIMIT
  500. ------------------------------------
  501. vertices per polygon            4
  502. polygons per object            32
  503. vertices per object           128
  504. objects in 3D world            32
  505. polygons per frame           1024
  506. ------------------------------------
  507.  
  508. That last limit came about as a result of maximum objects allowed in a 3d
  509. world and how many polygons there is allowed at most for each one of those
  510. polygons. Of course the more polygons and objects we have to process each
  511. frame, the slower the whole thing will get.
  512.  
  513.  
  514.  
  515. 6]    DATA STRUCTURES AND NEWTYPES
  516. _____________________________________________________________________________
  517.  
  518. Please look at DATASTRUCTS.DOC file for listing of NEWTYPE structures and
  519. other relevant information.
  520.  
  521.  
  522.  
  523. 7]    PLG OBJECT FILE FORMAT
  524. _____________________________________________________________________________
  525.  
  526. This file format is easy enough to understand so anyone can design their own
  527. objects and write them into a PLG file manually. This library does not support
  528. PLG files fully, because color information is handled here differently. Other
  529. than that everything is pretty much as in standard PLG files.
  530.  
  531. Format is very simple. It contains a list of vertices that comprise an object
  532. and a list of polygons as well. The first line is a header and contains
  533. the name of an object followed by number of vertices and number of polygons.
  534.  
  535. A list of all vertices follows next. Vertices must be presented in x, y, z
  536. form, with at least one space between each vertex. One vertex per line is
  537. allowed.
  538.  
  539. After that a list of polygons follows. One polygon per line is allowed. The
  540. first number is the color, then number of vertices in this polygon follows,
  541. followed by list of vertices that compose that polygon.
  542.  
  543. In real PLG file color information could be decimal or hexadecimal number, but
  544. this library can read only decimal numbers and that number contains no other
  545. information other than which register it is in a palette, whatever RGB value
  546. that may be. So there is no actual RGB value stored there, or shading, or
  547. special effect information like it would be in an actual PLG file. But that's
  548. all this library needs. If you would like indicate that a particular polygon
  549. should be a double sided polygon (that is it will be rendered regardless if
  550. it is with its front or back to viewer), you only need to add 4096 to the
  551. color register value. It will set the first bit of the last 4-bit nibble to
  552. one. The last four bits are supposed to contain additional information about
  553. a polygon, like special sahding, coloring, effects, etc... Currently 2B3D can
  554. only read if a polygon is onesided or two sided from that field.
  555.  
  556. Comments may be placed anywhere in a file. Anything followed by a '#' (number
  557. sign) or ';' (semicolon) until the end of the line is considered a comment
  558. and will be ignored by PLG reader.
  559.  
  560. Look up some .plg files that were included in this archive for examples of the
  561. format.
  562.  
  563.  
  564.  
  565. 8]    THINGS TO WATCH OUT FOR
  566. _____________________________________________________________________________
  567.  
  568. Constant shading is not really supported yet. Objects are expected to use
  569. flat shading when they are loaded from a .plg file.
  570.  
  571. Also, the entire objects and polygons get cut from the view if they cross
  572. clipping planes. Dividing polygons would create polys with more than four
  573. vertices (which is not supported here) and would further slow down the
  574. whole thing.
  575.  
  576.  
  577.  
  578. 9]    CONTACTING AUTHOR
  579. _____________________________________________________________________________
  580.  
  581. And that is it. This is my little attempt at having written a 3D game in
  582. Blitz2 and this is as far as I got. Hopefully in the near future I will be
  583. able to do some more work on this library and expand it further.
  584.  
  585. If you have any questions, comments, or wish to contact me, send me email at
  586. gorn4907@mars.rowan.edu or send mail to Maciej Gorny, 424A Victoria Ave.,
  587. Glassboro, NJ, 08028, USA. I hope you have as much fun using it as I had
  588. writing it. Take care!
  589.  
  590. Maciej Gorny
  591. gorn4907@mars.rowan.edu
  592. 424A Victoria Avenue
  593. Glassboro, NJ 08028
  594. USA
  595.  
  596.  __________________________________________________________________________
  597. |                                                                          |
  598. |  BlitzBasic II 3D Graphics Library. Copyright (C) 1996 Maciej R. Gorny.  |
  599. |__________________________________________________________________________|
  600.  
  601.